const disableDrag = (image) => {
  image.addEventListener('dragstart', function (event) {
    event.preventDefault()
  })
}

const createImageBox = (imgboxWidth, imgBoxHeight, top, left) => {
  const imageBox = document.createElement('div')
  imageBox.style.position = 'absolute'
  imageBox.style.top = `${top || 0}px`
  imageBox.style.left = `${left || 0}px`
  imageBox.style.width = `${imgboxWidth}px`
  imageBox.style.height = `${imgBoxHeight}px`
  imageBox.style.boxShadow = '2px 2px 10px 2px #a7a7a7'
  imageBox.style.transformOrigin = '0 0'
  imageBox.style.transform = 'translate(0, 0)'
  imageBox.style.willChange = 'transform, width, height'
  imageBox.style.userSelect = 'none'
  imageBox.style.resize = 'both'
  imageBox.style.cursor = 'pointer'
  return imageBox
}

const createImage = (src) => {
  const img = document.createElement('img')
  img.style.width = '100%'
  img.style.height = '100%'
  img.style.objectFit = 'cover'
  img.src = src
  disableDrag(img) // 禁止拖拽
  return img
}

const createImageBoxDrag = () => {
  const after = document.createElement('div')
  after.className = 'image-box-drag'
  after.style.position = 'absolute'
  after.style.right = '0px'
  after.style.bottom = '0px'
  after.style.width = '10px'
  after.style.height = '10px'
  after.style.backgroundColor = 'transparent'
  after.style.cursor = 'se-resize'
  after.style.zIndex = '1'
  return after
}

const createImageIcon = ({ src, type }) => {
  const img = document.createElement('img')
  img.src = src
  img.style.width = '30px'
  img.style.height = '30px'
  img.style.position = 'absolute'
  img.style.top = '0px'
  if (type === 'confirm') {
    img.style.right = `0px`
    img.style.transform = 'translate(50%, -50%)'
  }
  if (type === 'cancel') {
    img.style.left = `0px`
    img.style.transform = 'translate(-50%, -50%)'
  }
  disableDrag(img) // 禁止拖拽
  return img
}

const getPointInsideDrag = (x, y, el) => {
  if (!el) {
    return false
  }
  const rect = el.getBoundingClientRect()
  const left = x - rect.left
  const top = y - rect.top
  if (left >= 0 && left <= rect.width && top >= 0 && top <= rect.height) {
    return true
  }
  return false
}

class CreateImage {
  constructor(props) {
    this.container = props.container
    this.imageLeft = props.left || 0
    this.imageTop = props.top || 0
    this.imageWidth = props.width || 0
    this.imageHeight = props.height || 0
  }

  createImage({ src, width, height, left, top }, confirm, cancel) {
    const img = createImage(src)
    img.onload = () => {
      const { width: _width, height: _height } = img
      let imgboxWidth = width || 0
      let imgBoxHeight = height || 0

      if (!width && !height) {
        if (_height > this.containerRect.height) {
          imgBoxHeight = this.containerRect.height / 1.2
          imgboxWidth = (imgBoxHeight / _height) * _width
        } else {
          imgboxWidth = 400
          imgBoxHeight = (imgboxWidth / _width) * _height
        }
      }

      const imageBox = createImageBox(imgboxWidth, imgBoxHeight, top, left)
      const imageBoxDrag = createImageBoxDrag()

      const createUrl = (type) => {
        // return require(`@/static/${type}.png`)
      }

      const confirmImg = createImageIcon({ src: createUrl('confirm'), type: 'confirm' })
      confirmImg.addEventListener('click', () => {
        this.container.removeChild(imageBox)
        if (confirm) {
          confirm({
            image: img,
            left: this.imageLeft,
            top: this.imageTop,
            width: this.imageWidth,
            height: this.imageHeight
          })
        }
      })

      const cancelImg = createImageIcon({ src: createUrl('cancel'), type: 'cancel' })
      cancelImg.addEventListener('click', () => {
        this.container.removeChild(imageBox)
        cancel && cancel()
      })

      imageBox.appendChild(img)
      imageBox.appendChild(imageBoxDrag)
      imageBox.appendChild(confirmImg)
      imageBox.appendChild(cancelImg)
      this.container.appendChild(imageBox)
      this._setImageRectByImageBox(imageBox)
      this._registerImageBoxListener(imageBox)
    }

    return img
  }

  get containerRect() {
    return this.container.getBoundingClientRect()
  }

  _registerImageBoxListener(imageBox) {
    let moveX = 0
    let moveY = 0

    imageBox.onmousedown = (event) => {
      const startX = event.clientX
      const startY = event.clientY
      const children = imageBox.children
      const imageBoxDrag = Array.from(children).find((item) => item.className === 'image-box-drag')
      const isResizing = getPointInsideDrag(startX, startY, imageBoxDrag)

      window.onmousemove = (event) => {
        if (isResizing) {
          const rect = imageBox.getBoundingClientRect()
          const nWidth = Math.max(event.clientX - rect.left, 100)
          const nHeight = (nWidth / rect.width) * rect.height
          imageBox.style.width = `${nWidth}px`
          imageBox.style.height = `${nHeight}px`
        } else {
          const translateX = moveX + event.clientX - startX
          const translateY = moveY + event.clientY - startY
          imageBox.style.transform = `translate(${translateX}px , ${translateY}px)`
        }
        this._setImageRectByImageBox(imageBox)
      }

      window.onmouseup = (event) => {
        if (!isResizing) {
          moveX += event.clientX - startX
          moveY += event.clientY - startY
        }
        window.onmousemove = null
        window.onmouseup = null
      }
    }
  }

  _setImageRectByImageBox(imageBox) {
    const rect = imageBox.getBoundingClientRect()
    this.imageLeft = rect.left - this.containerRect.left
    this.imageTop = rect.top - this.containerRect.top
    this.imageWidth = rect.width
    this.imageHeight = rect.height
  }
}

export default CreateImage
